package it.unisannio.lesim.servlet;

import it.unisannio.lesim.dao.MessageDAO;
import it.unisannio.lesim.fsm.FSM;
import it.unisannio.lesim.fsm.Message;
import it.unisannio.lesim.parser.ParserXML;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;

/**
 * 
 * @author Marco Calisti
 * @author Antonio Cuomo
 * @author Rocco Mazzeo
 * @author Francesco Pacilio
 * 
 */

public class MessageServlet extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * 
     * @param request servlet request
     * @param response servlet response
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");

        String req = request.getRequestURI();

        if (req.equals("/AnalizzatoreSip/ReadConversations")) {
            readConversations(request, response);
        } else if (req.equals("/AnalizzatoreSip/ReadMessages")) {
            readMessages(request, response);
        } else if (req.equals("/AnalizzatoreSip/SelectFSM")) {
            selectFSM(request, response);
        } else if (req.equals("/AnalizzatoreSip/RunAnalyzer")) {
            runAnalyzer(request, response);
        } else if (req.equals("/AnalizzatoreSip/RunSingleMessage")) {
            runSingleMessage(request, response);
        } else if (req.equals("/AnalizzatoreSip/RunAllMessage")) {
            runAllMessage(request, response);
        } else if (req.equals("/AnalizzatoreSip/ReadFSMforDelete")) {
            readFSMforDelete(request, response);
        }
    }
    
    private void readFSMforDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            ParserXML parser = new ParserXML(this.getServletContext().getRealPath("FSM.xml"));

            HttpSession session = request.getSession();
            ArrayList fsms = parser.readFSMS();
            request.setAttribute("FSM", fsms);
            session.setAttribute("FSM_Temp", fsms);

            if (fsms.size() == 0) {
                request.setAttribute("Messaggio", "Non ci sono FSM da eliminare");
                gotoPage("/deleteFSM.jsp", request, response);
            } else {
                gotoPage("/deleteFSM.jsp", request, response);
            }

        } catch (Exception e) {
            request.setAttribute("Messaggio", "Si e' verificato un errore si prega di ripetere l'operazione");
            gotoPage("/index.jsp", request, response);
        }
    }

    private void runSingleMessage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            HttpSession session = request.getSession();
            ArrayList fsms = (ArrayList) session.getAttribute("FSM");
            ArrayList messages = (ArrayList) session.getAttribute("Messages");

            Message m = (Message) messages.get(0);

            for (int i = 0; i < fsms.size(); i++) {
                ((FSM) fsms.get(i)).receiveMessage(m);
            }

            //aggiorno le fsm nella sessione
            session.setAttribute("FSM", fsms);

            //rimuovo il messaggio gestito
            if (messages.size() == 1) {

                //gestisco l'ultimo messaggio
                messages.remove(m);
                session.setAttribute("Messages", messages);

                gotoPage("/results.jsp", request, response);
            } else {
                messages.remove(m);
                session.setAttribute("Messages", messages);

                gotoPage("/run.jsp", request, response);
            }
        } catch (Exception e) {
            request.setAttribute("Messaggio", "Si e' verificato un errore si prega di ripetere l'operazione");
            gotoPage("/index.jsp", request, response);
        }
    }

    private void runAllMessage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            HttpSession session = request.getSession();
            ArrayList fsms = (ArrayList) session.getAttribute("FSM");
            ArrayList messages = (ArrayList) session.getAttribute("Messages");

            for (int i = 0; i < messages.size(); i++) {
                Message m = (Message) messages.get(i);

                for (int j = 0; j < fsms.size(); j++) {
                    ((FSM) fsms.get(j)).receiveMessage(m);
                }
            }

            session.setAttribute("FSM", fsms);
            session.removeAttribute("Messages");
            //Simulare tutti i messaggi

            gotoPage("/results.jsp", request, response);
        } catch (Exception e) {
            request.setAttribute("Messaggio", "Si e' verificato un errore si prega di ripetere l'operazione");
            gotoPage("/index.jsp", request, response);
        }
    }

    private void runAnalyzer(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            String[] NameFSM = request.getParameterValues("fsm");

            if (NameFSM != null) {

                HttpSession session = request.getSession();
                ArrayList fsms = (ArrayList) session.getAttribute("FSM_Temp");
                session.removeAttribute("FSM_Temp");
                ArrayList fsm_temp = new ArrayList();
                for (int i = 0; i < fsms.size(); i++) {
                    String temp = (String) ((FSM) (fsms.get(i))).getName();

                    for (int j = 0; j < NameFSM.length; j++) {
                        String temp2 = (String) NameFSM[j];
                        //  System.out.println("Confronto la prima: !"+temp+"! con la seconda: !"+NameFSM[j]+"!");  
                        if (temp.equals(temp2)) {
                            fsm_temp.add(fsms.get(i));
                        }
                    }
                }

                //fsms sono gli oggetti FSM attivi
                session.setAttribute("FSM", fsm_temp);

                String[] messageNo = (String[]) session.getAttribute("messageNo");
                session.removeAttribute("messageNo");

                MessageDAO m = new MessageDAO();

                session.setAttribute("Messages", m.readMessagesFromIDs(messageNo));

                gotoPage("/run.jsp", request, response);
            } else {
                request.setAttribute("Messaggio", "Si prega di selezionare almeno una FSM");
                gotoPage("/index.jsp", request, response);
            }
        } catch (Exception e) {
            request.setAttribute("Messaggio", "Si e' verificato un errore si prega di ripetere l'operazione");
            gotoPage("/index.jsp", request, response);
        }
    }

    private void selectFSM(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            ParserXML parser = new ParserXML(this.getServletContext().getRealPath("FSM.xml"));

            //all'interno di messageNo, troviamo l'elenco degli id dei messaggi selezionati
            String[] messageNo = request.getParameterValues("message");
            HttpSession session = request.getSession();
            session.setAttribute("messageNo", messageNo);
            ArrayList fsms = parser.readFSMS();
            request.setAttribute("FSM", fsms);
            session.setAttribute("FSM_Temp", fsms);

            if (messageNo == null) {
                request.setAttribute("Messaggio", "Si prega di selezionare almeno un messaggio");
                gotoPage("/index.jsp", request, response);
            } else {
                gotoPage("/step3.jsp", request, response);
            }

        } catch (Exception e) {
            request.setAttribute("Messaggio", "Si e' verificato un errore si prega di ripetere l'operazione");
            gotoPage("/index.jsp", request, response);
        }
    }

    private void readConversations(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            MessageDAO m = new MessageDAO();
            request.setAttribute("Conversations", m.readConversations());
            gotoPage("/index.jsp", request, response);
        } catch (Exception e) {
            request.setAttribute("Messaggio", "Non e' stato possibile comunicare con il database.");
            gotoPage("/index.jsp", request, response);
        }
    }

    private void readMessages(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            MessageDAO m = new MessageDAO();

            request.setAttribute("Messages", m.readMessagesFromConversation((String) request.getParameter("conversation")));

            gotoPage("/step2.jsp", request, response);
        } catch (Exception e) {
            request.setAttribute("Messaggio", "Non e' stato possibile comunicare con il database.");
            gotoPage("/index.jsp", request, response);
        }
    }

    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     */
    public String getServletInfo() {
        return "Short description";
    }

    private void gotoPage(String url, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        RequestDispatcher dispacher = getServletContext().getRequestDispatcher(url);
        dispacher.forward(request, response);
    }
}
